// (C) 2021 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other 
// software and tools, and its AMPP partner logic functions, and any output 
// files from any of the foregoing (including device programming or simulation 
// files), and any associated documentation or information are expressly subject 
// to the terms and conditions of the Intel Program License Subscription 
// Agreement, Intel FPGA IP License Agreement, or other applicable 
// license agreement, including, without limitation, that your use is for the 
// sole purpose of programming logic devices manufactured by Intel and sold by 
// Intel or its authorized distributors.  Please refer to the applicable 
// agreement for further details.

module espi_port80_process
  (
   // Globals 
   input             clk,
   input             reset,

   // Avalon memory-mapped slave from BMC
   output reg [31:0] readdata,
   output reg        readdatavalid,
   input [1:0]       address,
   input             chipselect,
   input             write_n,
   input             read_n,
   input [31:0]      writedata,

   // Avalon memory-mapped slave from eSPI peripheral channel
   input wire [15:0] io_address,
   input wire        io_write,
   input wire [7:0]  io_writedata,

   // MSI-X to BMC
   output reg        espi_port80_msix_req,
   input wire        espi_port80_msix_ack
   );

    logic [31:0] pc_port80_data;
    logic        pc_port80_isr;
    logic [7:0]  p80_bytes_avail;
    logic        read_p80_isr;
    logic        read_p80_data;
    logic        read_n_1;
    logic        read_re;

    
    always_ff @(posedge clk, posedge reset) begin
        if (reset) begin
            read_n_1      <= 1'b1;
            readdata      <= 0;
            readdatavalid <= 0;
        end
        else begin
            read_n_1      <= read_n;
            readdatavalid <= ~read_n;
            if (read_re) begin
                case (address)
                  2'h0:   readdata  <= {p80_bytes_avail[7:0], {23{1'b0}}, pc_port80_isr};
                  2'h1:   readdata  <= pc_port80_data;
                  default: readdata <= 32'h1d53_1d53;
                endcase // case (address)
            end
        end
    end

    port80_if port80_if 
      (
       .p80_clk              ( clk                  ),
       .p80_reset            ( reset                ),
       .io_address           ( io_address           ),
       .io_write             ( io_write             ),
       .io_writedata         ( io_writedata         ),
       .p80_rd_data          ( pc_port80_data       ),
       .p80_rd_data_re       ( read_p80_data        ),
       .p80_rd_isr           ( pc_port80_isr        ),
       .p80_rd_isr_re        ( read_p80_isr         ),
       .p80_rd_bytes_avail   ( p80_bytes_avail      ),
       .espi_port80_msix_req ( espi_port80_msix_req ),
       .espi_port80_msix_ack ( espi_port80_msix_ack )
       );

    assign read_p80_isr  = read_re & (address == 2'd0);
    assign read_p80_data = read_re & (address == 2'd1);
    assign read_re = ~read_n & read_n_1;
    
endmodule
